package com.fulihui.systemcore.repository.impl;

import java.util.*;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import org.near.toolkit.common.StringUtil;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import com.fulihui.systemcore.dal.convertor.AreaConv;
import com.fulihui.systemcore.dal.convertor.CityConv;
import com.fulihui.systemcore.dal.convertor.ProvinceConv;
import com.fulihui.systemcore.dal.dataobj.PosCityDO;
import com.fulihui.systemcore.dal.mapper.PosAreaMapper;
import com.fulihui.systemcore.dal.mapper.PosCityMapper;
import com.fulihui.systemcore.dal.mapper.PosProvinceMapper;
import com.fulihui.systemcore.dto.PosAreaDTO;
import com.fulihui.systemcore.dto.PosCityDTO;
import com.fulihui.systemcore.dto.PosProvinceDTO;
import com.fulihui.systemcore.repository.CityModuleRepository;

/**
 * 
 * @author leeson 2016年5月25日 上午11:20:25
 */
@Repository
public class CityModuleRepositoryImpl implements CityModuleRepository {
    private static List<PosProvinceDTO>          provinceCache = new ArrayList<>();
    private static Map<String, List<PosCityDTO>> cityCache     = new HashMap<>();
    private static Map<String, List<PosAreaDTO>> areaCache     = new HashMap<>();

    private static Map<String, PosProvinceDTO>   provinceMap   = new HashMap<>();
    private static Map<String, PosCityDTO>       cityMap       = new HashMap<>();
    private static Map<String, PosAreaDTO>       areaMap       = new HashMap<>();

    @Autowired
    private PosProvinceMapper                    provinceMapper;
    @Autowired
    private PosCityMapper                        cityMapper;
    @Autowired
    private PosAreaMapper                        areaMapper;

    @PostConstruct
    public void init() {
        provinceCache = ProvinceConv.convert2List(provinceMapper.queryAll());
        if (null != provinceCache && provinceCache.size() > 0) {
            for (PosProvinceDTO province : provinceCache) {
                List<PosCityDTO> cityList = CityConv.convert2List(cityMapper.queryAll(province
                    .getCode()));
                cityCache.put(province.getCode(), cityList);
                provinceMap.put(province.getCode(), province);

                if (null != cityList && cityList.size() > 0) {
                    for (PosCityDTO city : cityList) {
                        List<PosAreaDTO> areaList = AreaConv.convert2List(areaMapper.queryAll(city
                            .getCode()));
                        areaCache.put(city.getCode(), areaList);
                        cityMap.put(city.getCode(), city);

                        if (null != areaList && areaList.size() > 0) {
                            for (PosAreaDTO area : areaList) {
                                areaMap.put(area.getCode(), area);
                            }
                        }
                    }
                }
            }
        }
    }

    @Override
    public List<PosProvinceDTO> queryProvinceAll() {
        if (CollectionUtils.isEmpty(provinceCache)) {
            return Collections.emptyList();
        }
        return Collections.unmodifiableList(provinceCache);
    }

    @Override
    public List<PosCityDTO> queryCityAll(String provinceCode) {
        if (CollectionUtils.isEmpty(cityCache)) {
            return Collections.emptyList();
        }
        List<PosCityDTO> cityList = cityCache.get(provinceCode);
        if (CollectionUtils.isEmpty(cityList)) {
            return Collections.emptyList();
        }
        return Collections.unmodifiableList(cityList);
    }

    @Override
    public List<PosAreaDTO> queryAreaAll(String cityCode) {
        if (CollectionUtils.isEmpty(areaCache)) {
            return Collections.emptyList();
        }
        List<PosAreaDTO> areaList = areaCache.get(cityCode);
        if (CollectionUtils.isEmpty(areaList)) {
            return Collections.emptyList();
        }
        return Collections.unmodifiableList(areaList);
    }

    @Override
    public PosProvinceDTO queryProvince(String provinceCode) {
        if (CollectionUtils.isEmpty(provinceMap)) {
            return null;
        }
        return provinceMap.get(provinceCode);
    }

    @Override
    public PosCityDTO queryCity(String cityCode) {
        if (CollectionUtils.isEmpty(cityMap)) {
            return null;
        }
        return cityMap.get(cityCode);
    }

    @Override
    public List<PosCityDTO> queryCitiesByCodes(List<String> codes) {
        if (CollectionUtils.isEmpty(codes)) {
            return Collections.emptyList();
        }
        List<PosCityDO> cityDOList = cityMapper.queryByCodes(codes);
        return CityConv.convert2List(cityDOList);
    }

    @Override
    public PosAreaDTO queryArea(String areaCode) {
        if (CollectionUtils.isEmpty(areaMap)) {
            return null;
        }
        return areaMap.get(areaCode);
    }

    @Override
    public PosCityDTO queryCapitalCityByProvinceCode(String provinceCode) {
        if (!CollectionUtils.isEmpty(cityCache)) {
            List<PosCityDTO> citys = cityCache.get(provinceCode);
            if (!CollectionUtils.isEmpty(citys)) {
                Collections.sort(citys, (o1, o2) -> {
                    /* int compare(PosCityDTO o1, PosCityDTO o2) 返回一个基本类型的整型，
                     * 返回负数表示：o1 小于o2， 返回0 表示：o1和o2相等， 返回正数表示：o1大于o2。
                     */
                    String o1Code = o1.getCode();
                    String o2Code = o2.getCode();
                    if (!StringUtil.isBlank(o1Code) && !StringUtil.isBlank(o2Code)) {
                        // 按照学生的年龄进行升序排列
                    if (Long.parseLong(o1Code) > Long.parseLong(o2Code)) {
                        return 1;
                    }
                    if (StringUtil.equals(o1.getCode(), o2.getCode())) {
                        return 0;
                    }
                }
                return -1;
            }   );
                return citys.get(0);
            }
        }
        return null;
    }

    @Override
    public List<PosCityDTO> queryHotCities() {
        List<PosCityDO> cityDOList = cityMapper.queryHotCities();
        return CityConv.convert2List(cityDOList);
    }

    @Override
    public boolean setHot(int hot, List<String> codes) {
        return CollectionUtils.isEmpty(codes) || cityMapper.setHot(hot, codes);
    }
}